package br.ufrj.dcc.xml.dynamicintervals;

import java.awt.Color;
import java.awt.Component;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JTextPane;
import javax.swing.plaf.ComponentUI;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Document;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;

public class XmlHighlighter extends DefaultStyledDocument {
	private static final long serialVersionUID = 1L;

/*	private Element rootElement;*/

	private HashMap<String, Color> keywords;

	private MutableAttributeSet style;

	private Color commentColor = Color.GREEN;

	private Pattern multiLineCommentDelimiterStart = Pattern.compile("<!--");

	private Pattern multiLineCommentDelimiterEnd = Pattern.compile("-->");

	public XmlHighlighter() {
		putProperty(DefaultEditorKit.EndOfLineStringProperty, "\n");

		/*rootElement = getDefaultRootElement();*/

		keywords = new HashMap<String, Color>();
		keywords.put("<", Color.blue);
		keywords.put(">", Color.blue);
		keywords.put("<\\", Color.blue);		

		style = new SimpleAttributeSet();
	}

	public void insertString(int offset, String str, AttributeSet attr)
			throws BadLocationException {
		super.insertString(offset, str, attr);
		processChangedLines(offset, str.length());
	}

	public void remove(int offset, int length) throws BadLocationException {
		super.remove(offset, length);
		processChangedLines(offset, length);
	}
	
	int i = 0;
	
	public void processChangedLines(int offset, int length)
			throws BadLocationException {
		String text = getText(0, getLength());
		highlightString(Color.BLACK, 0, getLength(), true, false);
		
		Pattern p = Pattern.compile("\\<([a-zA-Z0-9=\"_ ]*)>");			
		Matcher m = p.matcher(text);			
		while (m.find()) {
			highlightString(Color.BLUE, m.start(),text.length() - m.end(), true, true);
		}		
		Matcher mlcStart = multiLineCommentDelimiterStart.matcher(text);
		Matcher mlcEnd = multiLineCommentDelimiterEnd.matcher(text);

		while (mlcStart.find()) {
			if (mlcEnd.find(mlcStart.end()))
				highlightString(commentColor, mlcStart.start(),
						(mlcEnd.end() - mlcStart.start()), true, true);
			else
				highlightString(commentColor, mlcStart.start(), getLength(),
						true, true);
		}
	}

	public void highlightString(Color col, int begin, int length, boolean flag,
			boolean bold) {
		StyleConstants.setForeground(style, col);
		StyleConstants.setBold(style, bold);

		setCharacterAttributes(begin, length, style, flag);
	}

	class highlightKit extends StyledEditorKit {
		private static final long serialVersionUID = 1L;

		public Document createDefaultDocument() {
			return new XmlHighlighter();
		}
	}

	// Because Swing's JTextPane is retarded by default and doesn't allow you to
	// just flip a switch and turn off the FUCKING line-wrapping
	//
	// This overridden method was coded by somebody much smarter than I,
	// somebody
	// probably with an EGO the size of SUN MICROSYSTEMS.
	//
	// At SUN our motto is "Over-engineer everything so that nobody understands
	// it..."
	class NonWrappingTextPane extends JTextPane {
		private static final long serialVersionUID = 1L;

		// The method below is coutesy of Core Swing Advanced
		// Programming by Kim Topley
		//
		// Override getScrollableTracksViewportWidth
		// to preserve the full width of the text
		public boolean getScrollableTracksViewportWidth() {
			Component parent = getParent();
			ComponentUI ui = getUI();

			return parent != null ? (ui.getPreferredSize(this).width <= parent
					.getSize().width) : true;
		}
	}

	public XmlHighlighter(String args[]) {
/*		JFrame frame = new JFrame(
				"Syntax Highlighting Test <Use Java Keywords>");
		NonWrappingTextPane textPane = new NonWrappingTextPane();
		textPane.setFont(new Font("Monospaced", Font.PLAIN, 20));
		JScrollPane scroll = new JScrollPane(textPane);
		textPane.setEditorKit(new highlightKit());
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(scroll);
		frame.setSize(640, 480);
		frame.setVisible(true);*/
	}
}